//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package fs_dao

import (
	"context"
	"time"

	"gitcode.com/eteam/api-server/dao/common"
	"gitcode.com/eteam/proto-gen-go.git/fs_api"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
)

type FileInfoDbItem struct {
	FileId       string                 `bson:"_id"`
	FileName     string                 `bson:"fileName"`
	FsId         string                 `bson:"fsId"`
	FileSize     uint32                 `bson:"fileSize"`
	CreateTime   int64                  `bson:"createTime"`
	CreateUserId string                 `bson:"createUserId"`
	OwnerType    fs_api.FILE_OWNER_TYPE `bson:"ownerType"`
	OwnerId      string                 `bson:"ownerId"`
}

func (item *FileInfoDbItem) ToFileInfo() *fs_api.FileInfo {
	return &fs_api.FileInfo{
		FileId:       item.FileId,
		FileName:     item.FileName,
		FileSize:     item.FileSize,
		CreateTime:   item.CreateTime,
		CreateUserId: item.CreateUserId,
		OwnerType:    item.OwnerType,
		OwnerId:      item.OwnerId,
	}
}

type _FsFileDao struct {
	mc *mongo.Collection
}

func newFsFileDao(db *mongo.Database) (*_FsFileDao, error) {
	mc := db.Collection(common.DB_NS_FS + "file")
	_, err := mc.Indexes().CreateMany(context.Background(), []mongo.IndexModel{
		{
			Keys: bson.D{{"fsId", 1}},
		},
	})
	if err != nil {
		return nil, err
	}
	return &_FsFileDao{mc: mc}, nil
}

func (db *_FsFileDao) Get(ctx context.Context, fsId, fileId string) (*FileInfoDbItem, error) {
	retItem := &FileInfoDbItem{}
	err := db.mc.FindOne(ctx, bson.M{"_id": fileId, "fsId": fsId}).Decode(retItem)
	return retItem, err
}

func (db *_FsFileDao) ListById(ctx context.Context, fsId string, fileIdList []string) ([]*FileInfoDbItem, error) {
	if len(fileIdList) == 0 {
		return []*FileInfoDbItem{}, nil
	}
	cursor, err := db.mc.Find(ctx, bson.M{"_id": bson.M{"$in": fileIdList}, "fsId": fsId})
	if err != nil {
		return nil, err
	}
	retList := []*FileInfoDbItem{}
	err = cursor.All(ctx, &retList)
	return retList, err
}

func (db *_FsFileDao) ListByFsId(ctx context.Context, fsId string, dayBefore int) ([]*FileInfoDbItem, error) {
	createTime := (time.Now().UnixNano() / 1e6) - int64(dayBefore)*24*3600*1000

	cursor, err := db.mc.Find(ctx, bson.M{"fsId": fsId, "createTime": bson.M{"$lte": createTime}})
	if err != nil {
		return nil, err
	}
	retList := []*FileInfoDbItem{}
	err = cursor.All(ctx, &retList)
	return retList, err
}

func (db *_FsFileDao) Insert(ctx context.Context, dbItem *FileInfoDbItem) error {
	_, err := db.mc.InsertOne(ctx, dbItem)
	return err
}

func (db *_FsFileDao) Exist(ctx context.Context, fsId, fileId string) (bool, error) {
	count, err := db.mc.CountDocuments(ctx, bson.M{"_id": fileId, "fsId": fsId})
	return count > 0, err
}

func (db *_FsFileDao) Remove(ctx context.Context, fsId, fileId string) error {
	_, err := db.mc.DeleteOne(ctx, bson.M{"_id": fileId, "fsId": fsId})
	return err
}

func (db *_FsFileDao) SetOwner(ctx context.Context, fsId, fileId string, ownerType int32, ownerId string) error {
	_, err := db.mc.UpdateOne(ctx, bson.M{"_id": fileId, "fsId": fsId}, bson.M{"$set": bson.M{"ownerType": ownerType, "ownerId": ownerId}})
	return err
}
